package cn.wzy.service.impl;

import cn.wzy.dto.LoginDTO;
import cn.wzy.dto.SmsCodeDto;
import cn.wzy.enums.BaseConstants;
import cn.wzy.mapper.LogininfoMapper;
import cn.wzy.mapper.UserMapper;
import cn.wzy.pojo.Logininfo;
import cn.wzy.pojo.User;
import cn.wzy.results.ResponseResult;
import cn.wzy.service.VerifyCodeService;
import cn.wzy.utils.RedisCache;
import cn.wzy.utils.SmsUtil;
import cn.wzy.utils.VerifyCodeUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.HashMap;
import java.util.Objects;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

@Service
public class VerifyCodeServiceImpl implements VerifyCodeService {

    @Resource
    private RedisCache redisCache;
    @Resource
    private UserMapper userMapper;
    @Resource
    private LogininfoMapper logininfoMapper;
    /*
    * 获取图片验证码
    * */
    @Override
    public ResponseResult getImgCode(String imageCodeKey) {
//        随机数 加入到redis中
        String uuid = VerifyCodeUtils.generateVerifyCode(4);
        redisCache.setCacheObject(imageCodeKey,uuid,5, TimeUnit.MINUTES);
//        将随机数和图片结合起来
        try {
            String code = VerifyCodeUtils.VerifyCode(120, 40, uuid);
            return ResponseResult.okResult(code);
        } catch (IOException e) {
            return ResponseResult.errorResult(101,"获取图片异常");
        }
    }

    /*
    * 发送手机验证码
    * */
    @Override
    public ResponseResult sendSmsCodeRegister(SmsCodeDto smsCodeDto) {
//        校验手机号和图片验证码
        if (StringUtils.isBlank(smsCodeDto.getMobile())
                || StringUtils.isBlank(smsCodeDto.getImageCode())
                || StringUtils.isBlank(smsCodeDto.getImageCodeKey())) {
            return ResponseResult.errorResult(201, "参数错误，请重新输入！");
        }
        String imgCode = redisCache.getCacheObject(smsCodeDto.getImageCodeKey());
        if (StringUtils.isBlank(imgCode)) {
            return ResponseResult.errorResult(202, "图片验证码失效，请重新刷新验证码");
        }
        if (!imgCode.equalsIgnoreCase(smsCodeDto.getImageCode())) {
            return ResponseResult.errorResult(203, "图片验证码输入错误，请重新输入");
        }
//        判断手机号是否存在
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getPhone,smsCodeDto.getMobile());
        User user = userMapper.selectOne(queryWrapper);
        if (Objects.nonNull(user)){
            return ResponseResult.errorResult(101,"手机号已注册");
        }
//        redis中查询是否有手机验证码
        String mobileCode = redisCache.getCacheObject(BaseConstants.RedisContants.REGISTER_SMS_CODE+smsCodeDto.getMobile());
//        没有验证码加入redis中
        if (StringUtils.isBlank(mobileCode)){
            mobileCode = UUID.randomUUID().toString();
        }else {
            //        存在验证码，判断是否能够重新发送，能，更新过期时间
            if (redisCache.getCacheObjectExpireTime(BaseConstants.RedisContants.REGISTER_SMS_CODE+smsCodeDto.getMobile())>4*60){
//                不能
                return ResponseResult.errorResult(204,"请不要频繁发送，稍等60秒发送");
            }
        }
//        更新过期时间
        redisCache.setCacheObject(BaseConstants.RedisContants.REGISTER_SMS_CODE+smsCodeDto.getMobile(),mobileCode,5,TimeUnit.MINUTES);
//        日志

//        短信发送
        String content = String.format("你的验证码为%s,请在%s分钟之内使用！", mobileCode, 5);
//        SmsUtil.sendSms(smsCodeDto.getMobile(),content);
        System.out.println("已经成功发送了一条短信,内容为"+content);
        return ResponseResult.okResult();
    }

    @Override
    public ResponseResult sendSmsCodeLogin(LoginDTO loginDTO) {
        //        判断手机号是否存在
        LambdaQueryWrapper<Logininfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Logininfo::getPhone,loginDTO.getUsername());
        Logininfo logininfo = logininfoMapper.selectOne(queryWrapper);
        if (Objects.isNull(logininfo)){
            return ResponseResult.errorResult(100,"手机号没有注册过，请注册后使用！");
        }
//        redis中查询是否有手机验证码
        String mobileCode = redisCache.getCacheObject(BaseConstants.RedisContants.LOGIN__SMS_CODE+loginDTO.getUsername());
//        没有验证码加入redis中
        if (StringUtils.isBlank(mobileCode)){
            mobileCode = UUID.randomUUID().toString();
        }else {
            //        存在验证码，判断是否能够重新发送，能，更新过期时间
            if (redisCache.getCacheObjectExpireTime(BaseConstants.RedisContants.LOGIN__SMS_CODE+loginDTO.getUsername())>4*60){
//                不能
                return ResponseResult.errorResult(204,"请不要频繁发送，稍等60秒发送");
            }
        }
//        更新过期时间
        redisCache.setCacheObject(BaseConstants.RedisContants.LOGIN__SMS_CODE+loginDTO.getUsername(),mobileCode,5,TimeUnit.MINUTES);
//        日志

//        短信发送
        String content = String.format("你的登入验证码为%s,请在%s分钟之内使用！", mobileCode, 5);
//        SmsUtil.sendSms(smsCodeDto.getMobile(),content);
        System.out.println("已经成功发送了一条短信,内容为"+content);
        return ResponseResult.okResult();
    }

    /*
     * 发送wx绑定验证码
     * */
    @Override
    public ResponseResult sendSmsCodeBindWx(HashMap<String, String> param) {
//        校验手机号
        String phone = param.get("phone");
        if (StringUtils.isBlank(phone)){
            return ResponseResult.errorResult(201,"手机号不能为空");
        }
        // redis中查询判断是否存在验证码
        String code = redisCache.getCacheObject(BaseConstants.RedisContants.WX_SMS_BIND_CODE+phone);
//        没有验证码加入redis中
        if (StringUtils.isBlank(code)){
            code = UUID.randomUUID().toString();
        }else {
            //        存在验证码，判断是否能够重新发送，能，更新过期时间
            if (redisCache.getCacheObjectExpireTime(BaseConstants.RedisContants.WX_SMS_BIND_CODE+phone)>4*60){
//                不能
                return ResponseResult.errorResult(204,"请不要频繁发送，稍等60秒发送");
            }
        }
//        更新过期时间
        redisCache.setCacheObject(BaseConstants.RedisContants.WX_SMS_BIND_CODE+phone,code,5,TimeUnit.MINUTES);
//        日志

//        短信发送
        String content = String.format("你的验证码为%s,请在%s分钟之内使用！", code, 5);
//        SmsUtil.sendSms(smsCodeDto.getMobile(),content);
        System.out.println("已经成功发送了一条短信,内容为"+content);
        return ResponseResult.okResult();
    }


}
